package com.example.demo.service.impl;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ImageUtil;
import com.example.demo.exception.FieldException;
import com.example.demo.service.FileService;
import com.example.demo.utils.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tika.Tika;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * Created by lyc on 2019/6/7.
 */
@Slf4j
@Service
public class FileServiceImpl implements FileService{

    @Value("${host:http://127.0.0.1:8080}")
    private String host;

    @Value("${file.folder:images}")
    private String uploadFolder;

    private static String[] images = {"jpg","png","bmp","jpeg","gif"};

    private boolean isImage(InputStream inputStream){
        String type = FileTypeUtil.getType(inputStream);
        type = type == null?"":type.trim();
        return Arrays.asList(images).contains(type);
    }

    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {

         Assert.isTrue(!file.isEmpty(),"文件不能为空");
        log.info("[文件类型] - [{}]", file.getContentType());
        log.info("[文件名称] - [{}]", file.getOriginalFilename());
        log.info("[文件大小] - [{}]", file.getSize());
        log.info("[文件名] - [{}]", file.getName());
        // TODO 将文件写入到指定目录（具体开发中有可能是将文件写入到云存储/或者指定目录通过 Nginx 进行 gzip 压缩和反向代理，此处只是为了演示故将地址写成本地电脑指定目录）
        //File savePath = new File(request.getSession().getServletContext().getRealPath(/upload/")); 原来旧搞法 boot不靠谱
        File savePath = new File(uploadFolder);
        if (!savePath.exists()) {
            savePath.mkdirs();
        }
        //Tika tika = new Tika();
        //String filetype = tika.detect(file.getInputStream());
        //log.info("[文件类型工具提取] - [{}]", filetype);
        InputStream inputStream = file.getInputStream();
        String fileType = FileTypeUtil.getType(inputStream);
        log.info("[文件类型工具] - [{}]",  fileType);
        //获取图片宽高 用于限制
        if(isImage( file.getInputStream())){
            //这里不能使用 inputStream 流 读过一次 就没有
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            log.info("图片高 - [{}]",  bufferedImage.getHeight());
            log.info("图片宽 - [{}]",  bufferedImage.getWidth());

        }
        //可以考虑换一个名字
        String name = file.getOriginalFilename();
        String newName = IdUtil.objectId().concat(file.getOriginalFilename().substring(name.indexOf(".")));
        log.info("新name - [{}]",  newName);
        File newFile = new File(savePath, file.getOriginalFilename());
        file.transferTo(newFile);
        Map<String, String> result = new HashMap<>(16);
        result.put("contentType", file.getContentType());
        result.put("fileName", file.getOriginalFilename());
        result.put("fileSize", file.getSize() + "");

        return host+"/upload/"+newFile.getName();
    }

    public String uploads(MultipartFile[] files) throws IOException {
        if (files == null || files.length == 0) {
            throw new FieldException("文件不能为空");
        }
        List<String> results = new ArrayList<>();
        File savePath = new File(uploadFolder);
        if (!savePath.exists()) {
            savePath.mkdirs();
        }
        for (MultipartFile file : files) {
            // TODO Spring Mvc 提供的写入方式
            String url = upload(file,null);
            results.add(url);
        }
        return StringUtils.join(results,",");
    }

   public String uploadBase64(String image) throws IOException {
       File savePath = new File(uploadFolder);
       if (!savePath.exists()) {
           savePath.mkdirs();
       }
       // TODO BASE64 方式的 格式和名字需要自己控制（如 png 图片编码后前缀就会是 data:image/png;base64,）
       // TODO 防止有的传了 data:image/png;base64, 有的没传的情况
       String[] d = image.split("base64,");
       final File tempFile = new File(savePath, IdUtil.objectId()+"."+image.substring(image.indexOf("image")+6,image.indexOf("base64,")-1));

       final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
       FileCopyUtils.copy(bytes, tempFile);
       return host+"/upload/"+tempFile.getName();
   }



}
